﻿using System;
using System.Xml.Linq;
using Csla;
using Csla.Rules.CommonRules;

namespace Agnes.TaskManager.Models
{
    /// <summary>
    /// 任务循环信息
    /// </summary>
    public class CirculateInfo : ModelBase<CirculateInfo>
    {
        #region Csla Property

        ///<summary>
        ///CSLA Property Info #
        ///<see cref="CirculateType">
        /// See The Property : CirculateType
        ///</see>
        ///</summary>
        public static readonly PropertyInfo<CirculateType> CirculateTypeProperty =
            RegisterProperty<CirculateType>(c => c.CirculateType);

        ///<summary>
        ///CSLA Property Info #
        ///<see cref="StartTime">
        /// See The Property : StartTime
        ///</see>
        ///</summary>
        public static readonly PropertyInfo<DateTime> StartTimeProperty = RegisterProperty<DateTime>(c => c.StartTime);

        ///<summary>
        ///CSLA Property Info #
        ///<see cref="Weekdays">
        /// See The Property : Weekdays
        ///</see>
        ///</summary>
        public static readonly PropertyInfo<Weekdays> WeekdaysProperty = RegisterProperty<Weekdays>(c => c.Weekdays);

        ///<summary>
        ///CSLA Property Info #
        ///<see cref="MonthDay">
        /// See The Property : MonthDay
        ///</see>
        ///</summary>
        public static readonly PropertyInfo<int> MonthDayProperty = RegisterProperty<int>(c => c.MonthDay);

        ///<summary>
        ///[CSLA Property]:
        ///循环类型
        ///</summary>
        public CirculateType CirculateType
        {
            get { return GetProperty(CirculateTypeProperty); }
            set { SetProperty(CirculateTypeProperty, value); }
        }

        ///<summary>
        ///[CSLA Property]:
        ///开始时间
        ///</summary>
        public DateTime StartTime
        {
            get { return GetProperty(StartTimeProperty); }
            set { SetProperty(StartTimeProperty, value); }
        }

        ///<summary>
        ///[CSLA Property]:
        ///每星期循环天数(当且仅当CirculateType=Weekly的时候有效)
        ///</summary>
        public Weekdays Weekdays
        {
            get { return GetProperty(WeekdaysProperty); }
            set { SetProperty(WeekdaysProperty, value); }
        }

        ///<summary>
        ///[CSLA Property]:
        ///每个月第几天执行(当且仅当CirculateType=Monthly的时候有效)
        ///</summary>
        public int MonthDay
        {
            get { return GetProperty(MonthDayProperty); }
            set { SetProperty(MonthDayProperty, value); }
        }

        #endregion

        #region CSLA Method

        private XElement GetXml()
        {
            var el = new XElement("CirculateInfo",
                                  new XAttribute("CirculateType", CirculateType.ToString()),
                                  new XAttribute("StartTime", StartTime.ToShortTimeString()),
                                  new XAttribute("Weekdays", Weekdays.ToString()),
                                  new XAttribute("MonthDay", MonthDay));

            return el;
        }

        /// <summary>
        /// 新建
        /// </summary>
        /// <param name="createParam"></param>
        protected override void DoCreate(object createParam)
        {
            base.DoCreate(createParam);
            using (BypassPropertyChecks)
            {
                CirculateType = CirculateType.Daily;
                StartTime = DateTime.Now;
                Weekdays = Weekdays.Sunday;
                MonthDay = 1;
            }
        }

        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="fetchParam"></param>
        protected override void DoFetch(object fetchParam)
        {
            base.DoFetch(fetchParam);
            var el = fetchParam as XElement;
            using (BypassPropertyChecks)
            {
                CirculateType = (CirculateType) Enum.Parse(typeof (CirculateType), el.Attribute("CirculateType").Value);
                StartTime = DateTime.Parse(el.Attribute("StartTime").Value);
                Weekdays = (Weekdays) Enum.Parse(typeof (Weekdays), el.Attribute("Weekdays").Value);
                MonthDay = Int32.Parse(el.Attribute("MonthDay").Value);
            }
        }

        /// <summary>
        /// 保存到XML
        /// </summary>
        /// <param name="saveFunc">t=>[XElment].add(t)</param>
        public void SaveToXml(Action<XElement> saveFunc)
        {
            base.Save(true);
            saveFunc(GetXml());
            DataPortal_Update();
        }

        protected override void AddBusinessRules()
        {
            base.AddBusinessRules();
            AddWeekdaysRule();
        }

        #endregion

        #region CSLA Validation

        private void AddWeekdaysRule()
        {
            var r = new Lambda(WeekdaysProperty, t =>
                {
                    var h = t.Target as CirculateInfo;

                    if ((int) h.Weekdays == 0)
                    {
                        t.AddErrorResult("请选择其中一天或者几天");
                    }
                });

            BusinessRules.AddRule(r);
        }

        #endregion
    }
}